// 注意事项
// 1. 传引用返回 2. const传引用传参  3. 禁止自我拷贝  4. 处理旧数据  5.异常安全性问题

#include <iostream>
#include <cstring>

class CMyString
{
public:
    char *_data = nullptr;

private:
    void Init(char *data)
    {
        if (data != nullptr)
        {
            try
            {
                // 申请空间
                char *tmp = new char[strlen(data) + 1];
                if (tmp == nullptr)
                    throw std::bad_alloc();
                _data = tmp;
                // 拷贝数据
                strcpy(_data, data);
            }
            catch (std::bad_alloc &e)
            {
                std::cerr << "内存分配失败: " << e.what() << std::endl;
            }
        }
    }

public:
    // 构造函数
    CMyString(char *data)
    {
        Init(data);
    }
    // 拷贝构造
    CMyString(const CMyString &str)
    {
        Init(str._data);
    }
    // 赋值运算符重载
    CMyString &operator=(const CMyString &str)
    {
        // 防止自我拷贝
        if (this != &str)
        {
            // 构造一个临时对象
            CMyString tmp(str);
            // 交换对象内部的成员--最终_data数据会由CMyString的析构函数释放
            char *t_data = tmp._data;
            tmp._data = _data;
            _data = t_data;
        }
        return *this;
    }
    // 析构函数
    ~CMyString()
    {
        if (_data != nullptr)
        {
            delete[] _data;
            _data = nullptr;
            std::cout << "析构函数" << std::endl;
        }
    }
};

int main()
{
    // 构造
    char *str1 = "yuanshuai";
    CMyString cmystring1 = str1;
    std::cout << cmystring1._data << std::endl
              << std::endl;

    // 拷贝构造
    CMyString cmystring2(cmystring1);
    std::cout << cmystring2._data << std::endl
              << std::endl;

    // 赋值重载
    char *str2 = "nihaoa";
    CMyString cmystring3 = str2;
    cmystring1 = cmystring3;
    std::cout << cmystring2._data << std::endl
              << std::endl;
}